﻿using System.Collections.Generic;
using System.Linq;
using Gumini.JulaDB.Data;
using Gumini.JulaDB.DataTypes;
using Gumini.JulaDB.Interfaces;

namespace Gumini.JulaDB.Planner
{
    /// <summary>
    /// Creates an unique list of records (DISTINCT).
    /// </summary>
    internal class DistinctNode : UnaryPlanNode
    {
        readonly RowEqualityComparer _comparer;
        
        public DistinctNode(PlanNode child)
            : base(child)
        {
            _comparer = new RowEqualityComparer(child.GetColumns());
        }

        public override List<Row> Execute()
        {
            return Child.Rows.Distinct(_comparer).ToList();
        }

        private class RowEqualityComparer : IEqualityComparer<Row>
        {
            readonly List<DataType> _dataTypes;

            public RowEqualityComparer(IHeading<IColumn> columns)
            {
                _dataTypes = columns.Select(c => c.Type).ToList();
            }

            public bool Equals(Row x, Row y)
            {
                for (int i = 0; i < _dataTypes.Count; i++)
                {
                    if (_dataTypes[i].Compare(x[i], y[i]) != 0)
                        return false;
                }
                return true;
            }

            public int GetHashCode(Row obj)
            {
                return 1;
            }
        }

        protected override string GetNodeDescription()
        {
            return "UNIQUE";
        }
    }
}
